package com.klun.project.dal.common.interceptor;

import com.klun.project.log.Constants;
import com.klun.project.log.KLog;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;

import java.sql.Connection;
import java.sql.Statement;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

public class QueryInterceptor implements Interceptor, Constants {
	public static long LONG_SQL = 450L;
	public static final Map<String, String> DB_URL_MAPPER = new ConcurrentHashMap();
//	private static Logger LOGGER = Logger.getLogger("QueryInterceptor");
	private static KLog LOGGER = KLog.getLogger(QueryInterceptor.class);

	public QueryInterceptor() {
	}

	public Object intercept(Invocation invocation) throws Throwable {
//		Tracer buildTracer = LOGGER.buildTracer();
//		Span span = buildTracer.createEmpty();
		String sql = null;
		String url = null;
		Object inputData = null;

		StatementHandler statementHandler;
		try {
			statementHandler = (StatementHandler)invocation.getTarget();
			sql = statementHandler.getBoundSql().getSql();
			Statement statement = (Statement)invocation.getArgs()[0];
			Connection connection = statement.getConnection();
			url = getUrl(connection.getMetaData().getURL());
//			span = buildTracer.createSpan("SQL", "select.sql");
//			span.addEvent("SQL.Method", "select");
			inputData = statementHandler.getParameterHandler().getParameterObject();
			if (LOGGER.isDebugEnabled()) {
				String reflectionToString = "" + inputData;
				LOGGER.debug("JDBC_IN {} URL {} PARAM {}", new Object[]{sql, url, reflectionToString});
			}
		} catch (Throwable var19) {
			LOGGER.error("failed to create cat transaction", var19);
		}

		statementHandler = null;
		boolean var17 = false;

		Object var22;
		try {
			var17 = true;
			Object object = invocation.proceed();
//			span.success();
			var22 = object;
			var17 = false;
		} catch (Throwable var18) {
			String reflectionToString = "" + inputData;
			LOGGER.error("JDBC_EX {} URL {} PARAM {}", new Object[]{sql, url, reflectionToString});
//			span.failed(var18);
			throw var18;
		} finally {
			if (var17) {
//				span.addEvent("SQL.Database", url);
//				long var12 = span.getDurationInMillis();
//				if (var12 > LONG_SQL) {
//					span.addData("sql", sql);
//					LOGGER.warn("JDBC_LONG {}", sql);
//				}
//				span.close();
			}
		}

//		span.addEvent("SQL.Database", url);
//		long durationInMillis = span.getDurationInMillis();
//		if (durationInMillis > LONG_SQL) {
//			span.addData("sql", sql);
//			LOGGER.warn("JDBC_LONG {}", sql);
//		}
//
//		span.close();
		return var22;
	}

	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	public void setProperties(Properties properties) {
	}

	public static String getUrl(String orUrl) {
		if (DB_URL_MAPPER.get(orUrl) == null) {
			if (DB_URL_MAPPER.size() > 100) {
				return orUrl.split("\\?")[0];
			}

			DB_URL_MAPPER.put(orUrl, orUrl.split("\\?")[0]);
		}

		return (String)DB_URL_MAPPER.get(orUrl);
	}
}
